// Includes
#include "Logger.h"
#include "SystemHelpers.h"		// Include appropriate system helper file
#include "FileHelpers.h"		// File helper methods

#include <fstream>		// C++ file stream header
#include <string>		// C++ string type header
#include <cstdio>		// C library standard I/O

using namespace std;

#ifdef _WIN32
	#pragma warning (disable : 4996)		// Disable warning for unsafe sscanf() and sprintf()
#endif

namespace EraAstral
{
	namespace core
	{
		// Logger constructor
		Logger::Logger()
		{
		}
		
		// Logger destructor
		Logger::~Logger()
		{
			// Clear all log entries
			Clear();
		}
		
		// Posts a new entry in the logger
		void Logger::PostEntry(LogEntryType type, string message)
		{
			// Pointer to new entry struct
			LogEntry *newEntry = new LogEntry();
			
			// Set type and message
			newEntry->type = type;
			newEntry->message = message;
			
			// Get time as string
			string timeStr = GetTimeStr();
			// Set entry time parameters from string
			sscanf(timeStr.c_str(), "%02d:%02d:%02d", &newEntry->tm_hour, &newEntry->tm_min, &newEntry->tm_sec);

			// Push new entry to vector
			m_entries.push_back(newEntry);
		}
		
		// Flushes all entries to a file
		int Logger::FlushToFile(const char *fileName)
		{
			// Create file for log
			if (CreateFile(fileName) != 0)
			{
				// Error during file creation
				return 1;
			}
			
			// Open output file stream
			ofstream outputStream;
			outputStream.open(fileName, ios_base::out | ios_base::trunc);
			
			// Check for error
			if (!outputStream.is_open() || outputStream.fail())
				// Return error code
				return 2;
				
			// Write log file header
			outputStream << "Era Astral log file" << endl;
			outputStream << "Created " << GetTimeStr() << endl << endl;
			
			// Loop through entries and write to the file
			for (unsigned int i = 0; i < m_entries.size(); i++)
			{
				// Pointer to current entry
				LogEntry *entry = m_entries[i];
				// String representation of entry type
				const char *typeStr = "";
				switch (entry->type)
				{
					case LE_MESSAGE:
						typeStr = "Message: ";
						break;
					case LE_WARNING:
						typeStr = "Warning: ";
						break;
					case LE_ERROR:
						typeStr = "Error: ";
						break;
					default:
						break;
				}
				// Send data to file
				outputStream << (entry->tm_hour < 10 ? "0" : "") << entry->tm_hour << ":" << (entry->tm_min < 10 ? "0" : "") << 
								entry->tm_min << ":" << (entry->tm_sec < 10 ? "0" : "") << entry->tm_sec << " - ";
				outputStream << typeStr << entry->message << std::endl;
			}
			
			// Flush and close file stream
			outputStream.flush();
			outputStream.close();
		
			// Return successfully
			return 0;
		}
		
		// Clear all log entries
		void Logger::Clear()
		{
			// Loop through vector
			for (unsigned int i = 0; i < m_entries.size(); i++)
			{
				// Delete entry
				if (m_entries[i] != NULL)
				{
					delete m_entries[i];
					m_entries[i] = NULL;
				}
			}
			
			// Clear vector
			m_entries.clear();
		}
	}
}
